Broker Chain

Pointer Chain을 이용한 디자인 패턴에서 사슬은 매우 인위적이다.
책임 사슬을 구현하는 또 다른 방법은 중앙 집중화된 컴포넌트를 이용하는 것이다.
(해당 컴포넌트에서 게임에서 발생하는 모든 변경 작업의 목록을 관리- 이벤트 브로커)

이벤트 브로커는 매개자(mediator) 디자인 패턴이자, 관찰자(observer) 디자인 패턴이다.
struct Game{ //
signal<void(Query&)> queries;
}; // Boost.Signals2 signal
크리처의 필드를 읽는 작업은, 변경 작업 후 결과값이 확정난 이후가 되어야 한다.
조회 작업을 별도의 객체에 캡슐화해서 처리(커맨드 패턴)
//
struct Query{
string creature_name;
enum Argument{attack, defense} argument; //
int result;
};
class Creature{
Game& game;
int attack, defense;
public:
string name;
// Creature(Game& game, ...): game(gmae), ... { ... }
// ...
};
int Creature::get_attach() const {
Query q{name, Query::Argument::attack, attack};
game.queries(q); // game q.result
return q.result;
}
//
class CreatureModifier{
Game& game;
Creature& creature;
public:
CreatureModifier(Game& game, Creature& creature): game(game), creature(creature) {}
};
class DoubleAttackModifier: public CreatureModifier{
connection conn;
public:
DoubleAttackModifier(Game& game, Creature& creature): CreatureModifier(game, creature){
conn=gamequeries.connect([&](Query& q){ //
if(q.creature_name==creature.name &&
q.argument==Query::Argument::attack) q.result*=2;
});
}
~DoubleAttackModifier(){ conn.disconnect(); }
};
//
Game game;
Creature goblin{game, "Strong Goblin", 2, 2};
cout<<goblin<<endl;
// : Strong Goblin : 2 : 2
{
DoubleAttackModifier dam{game, goblin};
cout<<goblin<<endl;
// : Strong Goblin : 4 : 2
} // dam ( )
cout<<goblin<<endl;
// : Strong Goblin : 2 : 2